package com.taikang.base.page;

import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;

public class SqlServerPageHelper {

	public static String getLimitString(String sql, int offset, int limit,BoundSql boundSql,String primaryKey) {
		if (offset < 0) {
			offset = 0;
		}
		if (limit < 0) {
			limit = 0;
		}
		sql = sql.toLowerCase();
		if (sql.indexOf("top") != -1) {
			return sql;
		}
		String[] temp = sql.split("\\s");
		int index = ArrayUtils.indexOf(temp, "from");
		String tableName = null;
		while (StringUtils.isBlank(tableName = temp[index + 1])) {
			index++;
		}
		index = ArrayUtils.indexOf(temp, tableName);
		String alias = null;
		while (StringUtils.isBlank(alias = temp[index + 1])) {
			index++;
		}
		StringBuffer pageSql = new StringBuffer(sql.length() + 8);
		int afterSelectInsertPoint = getAfterSelectInsertPoint(sql);
		pageSql.append(sql).insert(afterSelectInsertPoint, " top " + limit);
		int orderByIndex = getOrderByIndex(sql);
		if (offset > 0 && sql.indexOf("where") != -1) {
			pageSql.insert(orderByIndex, " and " + alias
					+ "." + primaryKey + " not in (select top " + offset + " " + alias + "." + primaryKey + " "
					+ getFromClause(sql) + ")");
			List<ParameterMapping> mappings = boundSql.getParameterMappings();
			if(mappings.size()>0){
				mappings.addAll(mappings);
			}
		} else if (offset > 0) {
			pageSql.insert(orderByIndex, " where " + alias
					+ "." + primaryKey + " not in (select top " + offset + " " + alias + "." + primaryKey + " "
					+ getFromClause(sql) + ")");
		}
		return pageSql.toString();
	}

	private static String getFromClause(String sql) {
		int whereIndex = sql.toLowerCase().indexOf("from");
		if (whereIndex == -1) {
			return "";
		}
		return sql.substring(whereIndex);
	}

	private static int getOrderByIndex(String sql) {
		int orderIndex = sql.toLowerCase().lastIndexOf("order");
		if (orderIndex == -1) {
			return sql.length();
		}
		return orderIndex;
	}

	static int getAfterSelectInsertPoint(String sql) {
		int selectIndex = sql.toLowerCase().indexOf("select");
		int selectDistinctIndex = sql.toLowerCase().indexOf("select distinct");
		return selectIndex + (selectDistinctIndex != selectIndex ? 6 : 15);
	}

	public static void main(String[] args) throws Exception {
		String sql = "select top 10 tb.a,tb.b,tb.c,tb.d from tb1 tb where tb.a=1 and tb.b not in(select b from tb1 where c=2)";
		System.out.println(getFromClause(sql));
	}
}
